#include "EntityFactory.h"

using namespace PHYOgre;

EntityFactory::EntityFactory(){}
EntityFactory::EntityFactory(Ogre::SceneManager *iSceneManager)
	:mSceneManager(iSceneManager)
{
}


EntityFactory::~EntityFactory(void)
{
}

void EntityFactory::SetSceneManager(Ogre::SceneManager *iSceneManager)
{
	mSceneManager = iSceneManager;
}
Particle * EntityFactory::CreateParticle(const Ogre::String& iName, const Ogre::String& iModel, const ParticleDescriptor& iDesc,ShapeType iShape)const
{
	Ogre::SceneNode* node = mSceneManager->createSceneNode(iName);
	mSceneManager->getRootSceneNode()->addChild(node);
	Ogre::Entity* model = mSceneManager->createEntity(iName, Ogre::SceneManager::PT_SPHERE);
	
	node->attachObject(model);
	node->setScale(iDesc.scale);
	node->setPosition(iDesc.position);
	PHYOgre::Particle *particle = new PHYOgre::Particle();
	particle->SetNode(node);
	particle->SetMass(iDesc.mass);

	model->setQueryFlags(MASK_PARTICLE);

	model->setUserAny(Ogre::Any(static_cast<IntegrableInterface*>(particle)));
	
	return particle;
	
}
StaticPlane* EntityFactory::CreateStaticPlane(const Ogre::String& iName,const Ogre::String& iTexture, const Vector3& iNormal, const Real& iOffset,
												const Vector2& iDim, const RigidBodyDescriptor& iDesc) const
{
	Ogre::Plane plane(iNormal, iOffset);
	Ogre::MeshManager::getSingleton().createPlane(iName + "_Plane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
		plane, iDim.x, iDim.y, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);
	
	Ogre::Entity *planeEnt = mSceneManager->createEntity(iName, iName + "_Plane");

	Ogre::SceneNode* node = mSceneManager->createSceneNode(iName);
	mSceneManager->getRootSceneNode()->addChild(node);
	node->attachObject(planeEnt);
	planeEnt->setMaterialName(iTexture);
	
	Plane *p = new Plane(iNormal,iDim, iOffset );

	StaticPlane *ret = new StaticPlane(node,planeEnt);
	ret->SetShape(p);
	ret->SetFriction(iDesc.friction);
	ret->SetRestitution(iDesc.restitution);

	planeEnt->setUserAny(Ogre::Any(static_cast<IntegrableInterface*>(ret)));
	
	return ret;
}
RigidBody * EntityFactory::CreateRigidBody(const Ogre::String& iName, const Ogre::String& iModel, const RigidBodyDescriptor& iDesc,ShapeType iShape)const
{
	
	Ogre::SceneNode* node = mSceneManager->createSceneNode(iName);
	mSceneManager->getRootSceneNode()->addChild(node);
	Ogre::Entity* model = mSceneManager->createEntity(iName,iModel);
	node->attachObject(model);
	node->setScale(iDesc.scale);
	node->setPosition(iDesc.position);
	
	model->setQueryFlags(MASK_RIGID_BODY);
	
	RigidBody *rigidBody = new RigidBody();
	rigidBody->SetNode(node);
	rigidBody->SetMass(iDesc.mass);
	rigidBody->SetInertialTensor(iDesc.tensor);
	rigidBody->SetFriction(iDesc.friction);
	rigidBody->SetRestitution(iDesc.restitution);

	switch(iShape)
	{
	case SPHERE:
		{
		Sphere *sphereShape = new Sphere(iDesc.position,model->getBoundingRadius());
		rigidBody->SetShape(sphereShape);
		break;
		}
	case BOX:
		{
		Box *boxShape = new Box(iDesc.position,model->getBoundingBox().getAllCorners());
		rigidBody->SetShape(boxShape);
		break;
		}
	default:
		break;
//	case PLANE:
//		{
////			Plane * planeShape = new Plane();
//		break;
//		}
	}
	model->setUserAny(Ogre::Any(static_cast<IntegrableInterface*>(rigidBody)));
	
	return rigidBody;
}